package cn.ingenic.glasssync.screen.live;

import java.lang.ref.WeakReference;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.content.Context;
import android.view.Surface;
import android.view.SurfaceHolder;

public class RtspClient {

    static {
	System.loadLibrary("live_jni");
    }

    private static final String TAG = "RtspClient";
    private final boolean DEBUG = false;
    
    private Context mContext = null;
    private OnRtspClientListener mOnRtspClientListener = null;

    private static boolean mHandleEvent = false;
    private static EventHandler mEventHandler = null;

	// used by native
    private int mNativeContext = 0;
    private int mNativeWindow = 0;
    private native final void native_start(Object rtspclient_this, String url);
    private native final void native_stop();
    private native final void native_set_surface(Surface surfaace);
    private native final void native_set_audio_data(Object audioData);

    public RtspClient(Context context) {
	Looper looper;
	if ((looper = Looper.myLooper()) != null) {
	    mEventHandler = new EventHandler(this, looper);
	} else if ((looper = Looper.getMainLooper()) != null) {
	    mEventHandler = new EventHandler(this, looper);
	} else {
	    mEventHandler = null;
	}

	mContext = context;
    }

    public void start(String url) {
	if (DEBUG) Log.i(TAG, "start");
	native_start(new WeakReference<RtspClient>(this), url);
	mHandleEvent = true;
    }

    public void close() {
	if (DEBUG) Log.i(TAG, "close");
	mHandleEvent = false;
	native_stop();
    }

    public void setSurface(SurfaceHolder holder) {
    	if (DEBUG) Log.i(TAG, "setSurface");
	native_set_surface(holder.getSurface());
    }
    
    public void setAudioDataBuf(Object buffer) {
    	if (DEBUG) Log.i(TAG, "setAudioDataBuf ---> " + buffer);
    	native_set_audio_data(buffer);
    }

    public interface OnRtspClientListener {
	public void onVideoSizeChanged(int width, int height);
	public void onFrameState(int state);
	public void onStreamDisconnect();
	public void onAudioStream();
	public void onStreamDown();
    }
    
    public void setListener(OnRtspClientListener listener) {
	mOnRtspClientListener = listener;
    }

    private class EventHandler extends Handler {
	private RtspClient mRtspClient = null;

	public EventHandler(RtspClient rc, Looper looper) {
	    super(looper);
	    mRtspClient = rc;
	}
	
	private final int NATIVE_MSG_NOTIFY_FRAME_STATE = 0;
	private final int NATIVE_MSG_NOTIFY_STREAM_DOWN = 1;
	private final int NATIVE_MSG_NOTIFY_VIDEO_SIZE = 2;
	private final int NATIVE_MSG_NOTIFY_AUDIO_STREAM = 3;
	
	@Override
	public void handleMessage(Message msg) {
	    switch(msg.what) {
	    case NATIVE_MSG_NOTIFY_VIDEO_SIZE:
		if (DEBUG) Log.i(TAG, "NATIVE_MSG_NOTIFY_VIDEO_SIZE : " + msg.arg1 + "x" + msg.arg2);
		if (mOnRtspClientListener != null) 
		    mOnRtspClientListener.onVideoSizeChanged(msg.arg1, msg.arg2);
		break;

	    case NATIVE_MSG_NOTIFY_STREAM_DOWN:
		if (DEBUG) Log.i(TAG, "NATIVE_MSG_NOTIFY_STREAM_DOWN");
		if (mOnRtspClientListener != null)
		    mOnRtspClientListener.onStreamDown();
		break;

	    case NATIVE_MSG_NOTIFY_FRAME_STATE:
		if (DEBUG) Log.i(TAG, "NATIVE_MSG_NOTIFY_FRAME_STATE : " + msg.arg1);
		if (mOnRtspClientListener != null)
		    mOnRtspClientListener.onFrameState(msg.arg1);
		break;
	    case NATIVE_MSG_NOTIFY_AUDIO_STREAM:
		    if (DEBUG) Log.i(TAG, "NATIVE_MSG_NOTIFY_AUDIO_STREAM : " + msg.arg1);
		    if (mOnRtspClientListener != null)
			mOnRtspClientListener.onAudioStream();
		    break;
	    default:
		Log.e(TAG, "Unknown message type " + msg.what);
		break;
	    }
	}
    }

    private static void postEventFromNative(Object rtspclient_ref, int what, int arg1, int arg2, Object obj) {
    	RtspClient rc = (RtspClient)((WeakReference<RtspClient>)rtspclient_ref).get();
    	if (rc != null && RtspClient.mEventHandler != null) {
    	    Message m = RtspClient.mEventHandler.obtainMessage(what, arg1, arg2, obj);
    	    RtspClient.mEventHandler.sendMessage(m);
    	}
    }
     
}